# xlwings库使用 
# 基本介绍：用于Python与Excel之间的交互，可以轻松地从 Excel 调用 Python，也可以利用Python自动化操作Excel，调用VBA，非常方便。
# 基本使用方法：新建一个excel文件，取名为test.xlsx，并新建一个sheet，取名为firstSheet，在其A1单元格内插入字符串
import xlwings as xw
import numpy as np
# 一、工作簿操作
# 创建一个app应用，打开excel程序，不打开已有工作簿，visible是界面可视属性，True 表示打开操作Excel过程可见，add_book是是否添加新工作簿属性，add_book=False 表示启动app后不用新建个工作簿
app = xw.App(visible=True, add_book=False)
# 新建一个工作簿
wb = app.books.add()
# 新建一个sheet
sheet = wb.sheets.add('firstSheet')
# 向sheet的A1单元格插入字符串
sheet.range('A1').value = "Daniel"
# 保存工作簿
wb.save('test.xlsx')
# 关闭工作簿
wb.close()
# 关闭程序
app.quit()

# 创建一个app应用，打开Excel程序
app = xw.App(visible=True, add_book=False)
# 第一种方式：在excel程序中新建一个工作簿或者打开已有的工作簿，通过调用app对象
wb = app.books.open('test.xlsx')
# 新建一个sheet
sheet = wb.sheets.add('secondSheet')
# 向sheet的A1单元格插入字符串
sheet.range('A2').value = "Daniel"
# 保存工作簿
wb.save('test.xlsx')
# 关闭工作簿
wb.close()
# 关闭程序
app.quit()

# 创建一个app应用，打开Excel程序
app = xw.App(visible=True, add_book=False)
# 第二种方式：通过调用xlwings库中的Book()方法，打开已有的工作簿
wb = xw.Book("test.xlsx")
# 获取工作簿完整路径
print(wb.fullname)
# 获取工作簿名称
print(wb.name)
# 保存工作簿
wb.save('test.xlsx')
# 关闭工作簿
wb.close()
# 关闭程序
app.quit()

# 二、工作表操作
# 创建一个app应用，打开excel程序，不打开已有工作簿，visible是界面可视属性，True 表示打开操作Excel过程可见，add_book是是否添加新工作簿属性，add_book=False 表示启动app后不用新建个工作簿
app = xw.App(visible=True, add_book=False)
# 新建一个工作簿
workbook = app.books.add()
# 新建一个sheet
sheet = workbook.sheets.add('testSheet')
# 向sheet的A1单元格插入字符串
sheet.range('A1').value = "Daniel"

# 创建工作表对象
worksheet = workbook.sheets["testSheet"]  # 获取工作簿中名为testSheet的工作表
print(worksheet.name)  # 打印出工作表名称
worksheet1 = workbook.sheets[0]  # 获取工作簿中第一个工作表
print(worksheet1.name)  # 打印出工作表名称
# 批量创建工作表对象
worksheets = workbook.sheets  # 获取工作簿中所有工作表
print(worksheets)  # 打印出所有工作表对象
print(worksheets[0].name)  # 获取第一个工作表的名称
# 常用API
# 获取所有工作表
# listbook = workbook.sheets
# 打开原工作表
# sheet = workbook.sheets["原工作表名或索引位置"]
# 激活活动工作表
# sheet.activate()
# 表格清除
# sheet.clear() # 清除内容和样式
# sheet.clear_contents() # 清除内容
# sheet.delete() # 删除工作表

# 三、单元格操作
# 创建单元格对象
# workcontent = worksheet.range("单元格位置").value = "" # 参数可以是单个单元格也可以是个范围
workcontent = worksheet.range("A2:E2").value = ["姓名","年龄","性别","身高","体重",]  # 向A2:E2单元格写入数据
workcontent = worksheet.range("A3").value = "管理员"  # 给单元格赋值
workcontent = worksheet.range("B3").value = "20"  # 给单元格赋值
workcontent = worksheet.range("D3").value = "185"  # 给单元格赋值
# 向单元格写入数据
workcontent = worksheet.range("A4").value = "张三"
# workcontent = worksheet.range("B4").value = "=SUM(B3,D3)"  # 输入公式
workcontent = worksheet.range("B4").formula = "=SUM(B3,D3)"  # 输入公式
# 写入一行数据
workcontent = worksheet.range("A5:E5").value = ["姓名","年龄","性别","身高","体重",] # 向A5:E5单元格写入数据
workcontent = worksheet.range("A6").value = ["李四","20","男","180","70",]  # 默认向A6:E6单元格写入数据
workcontent = worksheet.range("A7").options(transpose=True).value = ["王五","20","男","180","70",]  # transpose = True 的作用将数据转置,再向A7:A11单元格写入数据
# 写入一列数据
workcontent = worksheet.range("F1:F5").options(transpose=True).value = ["100","120","140","160","180",] # 向F1:F5单元格写入数据
# 写入多行数据
workcontent = worksheet.range("A12").value = [["赵六", "20", "男", "180", "70"],["钱七", "21", "男", "180", "70"],]  # 向A12:E13单元格写入两行数据
# 写入多列数据
workcontent = worksheet.range("A14").options(transpose=True).value = [["赵六", "20", "男", "180", "70"],["钱七", "21", "男", "180", "70"],]  # 向A14:B18单元格写入数据
# 注意：不能写入集合，如果传入一个完整的字典时只会插入key

# 读取表格中的数据
workcontent = worksheet.range("a1").value  # 获取A1单元格的数据
print("A1单元格的数据：",workcontent)
workcontent = worksheet.range("A2:E2").value  # 获取A2:E2单元格的数据
print("获取A2:E2单元格的数据：",workcontent)
workcontent = (worksheet.range("A3:E3").options(np.array,).value)  # 获取A3:E3单元格的数据
print("获取A3:E3单元格的数据：",workcontent)
# 获取有效内容的数据
workdata = worksheet.used_range.value  # 获取有效内容的数据，并将数据封装成list类型
print("有效内容的数据：",workdata)

# 获取表格有效内容的位置
workaddress = worksheet.used_range.address  # 返回excel数据最后一个单元格的绝对地址，但是该地址为str类型
print("获取表格有效内容的位置（绝对地址）：",workaddress)
workaddress = worksheet.used_range.address.replace("$", "")  # 去除$符号,绝对地址转为相对地址
print("获取表格有效内容的位置（相对地址）：",workaddress)

# 灵活获取Range有效范围的内容
workdata = worksheet.range("A2").expand("table").value  # 从指定的A2单元格开始获取有效内容
print("指定的A2单元格开始获取有效内容：",workdata)
workdata = worksheet.range("A2").options(expand="table").value  # 从指定的A2单元格开始获取有效内容
print("指定的A2单元格开始获取有效内容：",workdata)
# 常用API

# 获取指定sheet中的数据行数
sheet_rows = worksheet.used_range.last_cell.row  # 获取数据行数
print("获取指定sheet中的数据行数：",sheet_rows)
# 获取指定sheet中的数据列数
sheet_cols = worksheet.used_range.last_cell.column  # 获取数据列数
print("获取指定sheet中的数据列数：",sheet_cols)
# 删除指定的sheet
# workbook.sheets("Sheet1").delete()  # 删除名为Sheet1的工作表
# 按照索引删除指定sheet
# workbook.sheets[1].delete()  # 删除第二个工作表
# 删除指定单元格数据
worksheet.range("F2").clear()  # 清除F2单元格的数据
# 删除指定范围内单元格数据
worksheet.range("F4:E5").clear()  # 清除F2:F5单元格的数据
# 合并单元格
worksheet.range("G2:H2").merge()
# 拆分单元格
# worksheet.range("G2:H2").unmerge()
# 向指定单元格添加超链接文本，add_hyperlink(address,text_to_display, screen_tip)
worksheet.range("B1").add_hyperlink("https://www.baidu.com")
worksheet.range("C1").add_hyperlink(address="https://www.baidu.com",text_to_display="百度", screen_tip="百度一下")
worksheet.range("D1").add_hyperlink("https://www.baidu.com","百度","百度一下")
# 获取超链接
link = worksheet.range("B1").hyperlink
print("获取B1超链接：",link)
# 自动调试指定单元格高度和宽度
worksheet.range("A1").autofit()
# 设置指定单元格背景颜色
worksheet.range("B1:D1").color = (255,125,65)
# 返回指定范围内的第一列编号数字
num = worksheet.range("B2:D2").column
print("返回指定范围内的第一列编号数字：",num)
# 获取指定单元格的行高列宽
A1_row_height = worksheet.range("A1").row_height
A1_column_width = worksheet.range("A1").column_width
print("获取A1单元格的行高：",A1_row_height) 
print("获取A1单元格的列宽：",A1_column_width) 
# 设置指定单元格的行高列宽
worksheet.range("A1").row_height = 25
worksheet.range("A1").column_width = 30

# 设置指定单元格字体颜色
worksheet.range("A3").font.color = (255,125,65)
# 设置指定单元格字体
worksheet.range("A3").font.name = "微软雅黑"
# 设置指定单元格字体大小
worksheet.range("A3").font.size = 28
# 设置指定单元格字体加粗
worksheet.range("A3").font.bold = True
# 设置指定单元格字体斜体
worksheet.range("A3").font.italic = True
# 设置数字格式
worksheet.range("B3").number_format = "0.00"
# worksheet.range("B3").number_format = "0.00%"

# 保存工作簿
workbook.save('example.xlsx')
# 关闭工作簿
workbook.close()
# 关闭程序
app.quit()

